package com.self.shortlink.admin.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.self.shortlink.admin.common.convention.result.Result;
import com.self.shortlink.admin.remote.ShortLinkActualRemoteService;
import com.self.shortlink.admin.remote.dto.resp.ShortLinkStatsAccessRecordRespDTO;
import com.self.shortlink.admin.remote.dto.resp.ShortLinkStatsRespDTO;
import com.self.shortlink.admin.service.StatsAggregationService;
import com.self.shortlink.admin.service.dto.AggregatedStatsRespDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Service
@RequiredArgsConstructor
public class StatsAggregationServiceImpl implements StatsAggregationService {

    private final ShortLinkActualRemoteService shortLinkActualRemoteService;
    private final Executor executor = Executors.newFixedThreadPool(8);

    @Override
    public AggregatedStatsRespDTO aggregateForShortLink(String fullShortUrl,
                                                        String gid,
                                                        Integer enableStatus,
                                                        String startDate,
                                                        String endDate,
                                                        Long current,
                                                        Long size) {
        // 兜底：若前端未传时间，则使用 最近7天 到 当前日 的窗口
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate end = endDate == null || endDate.isEmpty() ? LocalDate.now() : LocalDate.parse(endDate.substring(0, 10), df);
        LocalDate start = startDate == null || startDate.isEmpty() ? end.minusDays(6) : LocalDate.parse(startDate.substring(0, 10), df);
        String startStr = start.format(df);
        String endStr = end.format(df);
        String startDateTime = startStr + " 00:00:00";
        String endDateTime = endStr + " 23:59:59";

        AggregatedStatsRespDTO resp = new AggregatedStatsRespDTO();

        CompletableFuture<Result<ShortLinkStatsRespDTO>> overviewF = CompletableFuture.supplyAsync(() ->
                shortLinkActualRemoteService.oneShortLinkStats(fullShortUrl, gid, enableStatus, startStr, endStr), executor);

        // 访问记录分页
        CompletableFuture<Result<Page<ShortLinkStatsAccessRecordRespDTO>>> accessPageF = CompletableFuture.supplyAsync(() ->
                shortLinkActualRemoteService.shortLinkStatsAccessRecord(fullShortUrl, gid, startDateTime, endDateTime, enableStatus, current, size), executor);

        // 其它分布/曲线等均已包含在 ShortLinkStatsRespDTO 中（依赖项目侧返回结构）。

        boolean[] partial = {false};

        CompletableFuture.allOf(overviewF, accessPageF).join();

        try {
            Result<ShortLinkStatsRespDTO> overviewR = overviewF.get();
            if (overviewR != null && overviewR.isSuccess()) {
                resp.setOverview(overviewR.getData());
            } else {
                partial[0] = true;
            }
        } catch (Exception e) {
            partial[0] = true;
        }

        try {
            Result<Page<ShortLinkStatsAccessRecordRespDTO>> pageR = accessPageF.get();
            if (pageR != null && pageR.isSuccess()) {
                resp.setAccessRecordPage(pageR.getData());
            } else {
                partial[0] = true;
            }
        } catch (Exception e) {
            partial[0] = true;
        }

        // 兼容：如果项目侧未提供细分字段，可留空，避免前端 NPE
        if (resp.getDailySeries() == null) resp.setDailySeries(Collections.emptyList());
        if (resp.getHourSeries() == null) resp.setHourSeries(Collections.emptyList());
        if (resp.getProvinceStats() == null) resp.setProvinceStats(Collections.emptyList());
        if (resp.getBrowserStats() == null) resp.setBrowserStats(Collections.emptyList());
        if (resp.getOsStats() == null) resp.setOsStats(Collections.emptyList());
        if (resp.getDeviceStats() == null) resp.setDeviceStats(Collections.emptyList());
        if (resp.getNetworkStats() == null) resp.setNetworkStats(Collections.emptyList());
        if (resp.getTopIp() == null) resp.setTopIp(Collections.emptyList());
        if (resp.getUvTypeSummary() == null) resp.setUvTypeSummary(new HashMap<>());

        resp.setPartial(partial[0]);
        return resp;
    }
}


